#!/usr/bin/python3
import os
from utils import String_Util, My_Util2
from .Entity import Entity
from .Biz_Method import Biz_Method
from wrappers.OpenAPI_Wrapper import openapi, get_api_annotation, get_includes


class Controller(Biz_Method):
    """
    控制器代码
    """

    def __init__(self, context, entity: Entity) -> None:
        self.context = context
        self.entity: Entity = entity
        self.api_path: str = String_Util.api_path(self.entity.table_name)
        self.prefix: str = self.entity.table_name.split("_")[0].lower()
        self.my_util2 = My_Util2.My_Util(self.context)

    def code_includes(self):
        package = self.entity.package
        prefix = self.entity.table_name.split("_")[0].lower()
        entity_name = self.entity.name
        includes = list()

        includes.append(
            f"""import com.baomidou.mybatisplus.extension.plugins.pagination.Page;"""
        )
        includes.append(f"""import {package}.internal.security.GetAccessControl;""")
        includes.append(f"""import {package}.internal.security.PostAccessControl;""")
        includes.append(f"""import {package}.internal.transaction.BusinessException;""")
        includes.append(f"""import {package}.{prefix}.bo.{entity_name}BO;""")
        for field in self.entity.fields:
            if field.ignore():
                continue
            if field.is_sort():
                includes.append(f"""import {package}.internal.model.SwapBO;""")
        includes.append(
            f"""import {package}.{prefix}.query.exists.{entity_name}Exists;"""
        )
        includes.append(f"""import {package}.{prefix}.bo.{entity_name}UpdateBO;""")
        includes.append(f"""import {package}.{prefix}.query.{entity_name}QueryInfo;""")
        includes.append(f"""import {package}.{prefix}.service.I{entity_name}Service;""")
        includes.append(f"""import {package}.{prefix}.vo.{entity_name}VO;""")
        includes.append(f"""import com.we7.platform.base.result.PageResult;""")
        includes.append(f"""import com.we7.platform.base.result.ResponseData;""")
        includes += get_includes("api")
        includes.append(f"""import lombok.RequiredArgsConstructor;""")
        includes.append(
            f"""import org.springframework.web.bind.annotation.RequestBody;"""
        )
        includes.append(
            f"""import org.springframework.web.bind.annotation.RequestMapping;"""
        )
        includes.append(
            f"""import org.springframework.web.bind.annotation.RequestParam;"""
        )
        includes.append(
            f"""import org.springframework.web.bind.annotation.RestController;"""
        )
        includes.append(f"""import java.util.List;""")
        includes = self.my_util2.sort_import_order(includes)
        return "\r".join(includes)

    @openapi(type="api")
    def code_save(self):
        entity_name = self.entity.name
        object_name = entity_name[:1].lower() + entity_name[1:]
        comment = self.entity.comment
        return f"""
    @PostAccessControl("/add")
    public ResponseData<Boolean> add(@RequestBody {entity_name}BO {object_name}BO) throws BusinessException {"{"}
        return ResponseData.data({object_name}Service.save({object_name}BO));
    {"}"}"""

    @openapi(type="api")
    def code_remove_list(self):
        entity_name = self.entity.name
        object_name = entity_name[:1].lower() + entity_name[1:]
        comment = self.entity.comment
        return f"""
    @PostAccessControl("/deleteByIds")
    public ResponseData<Boolean> deleteByIds(@RequestParam String ids) throws BusinessException {"{"}
        return ResponseData.data({object_name}Service.remove{entity_name}ByIds(ids));
    {"}"}"""

    @openapi(type="api")
    def code_update(self):
        entity_name = self.entity.name
        object_name = entity_name[:1].lower() + entity_name[1:]
        comment = self.entity.comment
        return f"""
    @PostAccessControl("/updateById")
    public ResponseData<Boolean> updateById(@RequestBody {entity_name}UpdateBO {object_name}UpdateBO) throws BusinessException {"{"}
        return ResponseData.data({object_name}Service.update{entity_name}ById({object_name}UpdateBO));
    {"}"}"""

    @openapi(type="api")
    def code_nullify_or_revert(self):
        entity_name = self.entity.name
        object_name = entity_name[:1].lower() + entity_name[1:]
        comment = self.entity.comment
        return f"""
    @PostAccessControl("/nullifyOrRevertByIds")
    public ResponseData<Boolean> nullifyOrRevertByIds(@RequestParam String ids) throws BusinessException {"{"}
        return ResponseData.data({object_name}Service.nullifyOrRevertByIds(ids));
    {"}"}"""

    @openapi(type="api")
    def code_swap(self):
        entity_name = self.entity.name
        object_name = entity_name[:1].lower() + entity_name[1:]
        comment = self.entity.comment
        return f"""
    @PostAccessControl("/swap")
    public ResponseData<Boolean> swap{entity_name}(@RequestBody SwapBO swapBO) throws BusinessException {"{"}
        return ResponseData.data({object_name}Service.swap{entity_name}(swapBO));
    {"}"}"""

    @openapi(type="api")
    def code_get(self):
        entity_name = self.entity.name
        object_name = entity_name[:1].lower() + entity_name[1:]
        comment = self.entity.comment
        return f"""
    @GetAccessControl("/findById")
    public ResponseData<{entity_name}VO> findById(@RequestParam Long id) {"{"}
        return ResponseData.data({object_name}Service.getById(id));
    {"}"}"""

    @openapi(type="api")
    def code_get_by_condition(self):
        entity_name = self.entity.name
        object_name = entity_name[:1].lower() + entity_name[1:]
        comment = self.entity.comment
        return f"""
    @GetAccessControl("/getByCondition")
    public ResponseData<{entity_name}VO> getByCondition({entity_name}Exists {object_name}Exists) {"{"}
        return ResponseData.data({object_name}Service.getByCondition({object_name}Exists));
    {"}"}"""

    @openapi(type="api")
    def code_page(self):
        entity_name = self.entity.name
        object_name = entity_name[:1].lower() + entity_name[1:]
        comment = self.entity.comment
        return f"""
    @GetAccessControl("/findPage")
    public PageResult<List<{entity_name}VO>> findPage({entity_name}QueryInfo {object_name}QueryInfo) {"{"}
        Page<{entity_name}VO> page = {object_name}Service.getPageByQueryInfo({object_name}QueryInfo, null);
        return PageResult.page(page.getTotal(), page.getRecords());
    {"}"}"""

    @openapi(type="api")
    def code_list(self):
        entity_name = self.entity.name
        object_name = entity_name[:1].lower() + entity_name[1:]
        comment = self.entity.comment
        return f"""
    @GetAccessControl("/list")
    public ResponseData<List<{entity_name}VO>> list({entity_name}Exists {object_name}Exists) {"{"}
        return ResponseData.data({object_name}Service.list({object_name}Exists));
    {"}"}"""

    @openapi(type="api")
    def code_next_sort(self):
        entity_name = self.entity.name
        object_name = entity_name[:1].lower() + entity_name[1:]
        return f"""
    @GetAccessControl("/getNextSortNumber")
    public ResponseData<Integer> getNextSortNumber() {"{"}
        return ResponseData.data({object_name}Service.getNextSortNumber());
    {"}"}"""

    @openapi(type="api")
    def code_exists(self):
        entity_name = self.entity.name
        object_name = entity_name[:1].lower() + entity_name[1:]
        comment = self.entity.comment
        return f"""
    @GetAccessControl("/exists")
    public ResponseData<Boolean> exists({entity_name}Exists {object_name}Exists) {"{"}
        return ResponseData.data({object_name}Service.exists({object_name}Exists));
    {"}"}"""

    def code(self):
        author = self.entity.author
        package = self.entity.package
        entity_name = self.entity.name
        object_name = entity_name[:1].lower() + entity_name[1:]
        api_path = self.api_path
        comment = self.entity.comment
        prefix = self.prefix

        includes = self.code_includes()

        codes = list()
        save = self.code_save()
        codes.append(save)
        remove_list = self.code_remove_list()
        codes.append(remove_list)
        update = self.code_update()
        codes.append(update)
        if self.entity.has_status():
            codes.append(self.code_nullify_or_revert())
        if self.entity.has_sort():
            codes.append(self.code_swap())
        get = self.code_get()
        codes.append(get)
        # get_by_condition = self.code_get_by_condition()
        # codes.append(get_by_condition)
        page = self.code_page()
        codes.append(page)
        code_list = self.code_list()
        codes.append(code_list)
        if self.entity.has_sort():
            codes.append(self.code_next_sort())
        exists = self.code_exists()
        codes.append(exists)
        codes = "\r".join(codes)

        return f"""package {package}.{prefix}.controller;

{includes}

/**
 * <p>
 * {comment}接口控制器
 * </p>
 *
 * @author {author}
 */
{get_api_annotation(comment)}
@RestController
@RequestMapping("{api_path}")
@RequiredArgsConstructor
public class {entity_name}Controller {'{'}

    private final I{entity_name}Service {object_name}Service;
{codes}
{'}'}
"""

    def save_file(self, dir):
        _target_dir = os.path.join(dir, self.prefix, "controller")
        if not os.path.exists(_target_dir):
            os.makedirs(_target_dir)
        with open(
            os.path.join(_target_dir, "{}Controller.java".format(self.entity.name)),
            mode="w",
            encoding="utf-8",
        ) as f:
            f.write(self.code())
